


class History{
    constructor() {
        this.lstUndo = [];
        this.lstRedo = [];

        this.lastCmdTimeMs = Date.now();
        this.idCounter = 0;
    }

    execute(cmd){
        let lastCmd = this.lstUndo[this.lstUndo.length - 1];
        let timeDifference = Date.now() - this.lastCmdTimeMs;

        let isUpdatableCmd = false;
        if( lastCmd &&
            lastCmd.updatable &&
            cmd.updatable &&
            lastCmd.type === cmd.type){
            isUpdatableCmd = true;
        }

        if(isUpdatableCmd && timeDifference < 500){
            lastCmd.update(cmd);
            cmd = lastCmd;
        }else{
            this.lstUndo.push(cmd);
            cmd.id = ++this.idCounter;
        }

        cmd.execute();
        this.lastCmdTimeMs = Date.now();

        // 清除所有的redo
        this.lstRedo.length = 0;

        // TODO: 更新历史记录相关UI dispatch / emit ......

        // 最多支持200条编辑记录
        if(this.lstUndo.length > 200){
            this.lstUndo.shift();
        }
    }

    undo(){
        if(this.lstUndo.length < 1){
            cc.log('no undo cmd!');
            return;
        }

        let cmd = this.lstUndo.pop();
        cc.log('history undo:',cmd.id);
        cc.log('cmd:', cmd);
        cmd.undo();
        this.lstRedo.push(cmd);

        // TODO: 更新相关UI

        return cmd;
    }

    redo(){
        if(this.lstRedo.length < 1){
            cc.log('no redo cmd!');
            return;
        }
        let cmd = this.lstRedo.pop();
        cc.log('history redo:',cmd.id);
        cc.log('cmd:', cmd);
        cmd.execute();
        this.lstUndo.push(cmd);

        // TODO：更新相关UI

        return cmd;
    }

    clean(){
        this.lstRedo.length = 0;
        this.lstUndo.length = 0;
        this.idCounter = 0;

        // TODO: 更新相关UI
    }

    getAllCmds(){
        let cmds = [];
        for(let i = 0,len = this.lstUndo.length; i < len; ++i){
            let cmd = this.lstUndo[i];
            cmds.push(cmd);
        }

        for(let i = 0,len = this.lstRedo.length; i < len; ++i){
            let cmd = this.lstRedo[i];
            cmds.push(cmd);
        }

        return cmds;
    }
}

module.exports = History;
